import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:dio/dio.dart' as minedio;
import 'package:flutter/material.dart';

import 'package:get_storage/get_storage.dart';

import '../const/AppConst.dart';
import '../event/DataCallBack.dart';
import '../logs/Logger.dart';
import '../utils/CommonUtil.dart';
import '../utils/tips.dart';


class NetWorkManager {
  // 开发环境
  // static String HOST_IP = "zxlab-dev.ubtrobot.com";

  //对外测试环境.
  static String HOST_IP = 'sdk-test.newtranx.com/dev-apis/';
  //https://zxcnagent.ubtrobot.com
  static String WS_IP = 'xy-apis.newtranx.com/';


  static String APIPort1 = HOST_IP + "/";

  //业务服务器地址.
  static String mServerHost = "http://" + APIPort1;
  // localhost
  //static String mServerHost = "http://10.10.17.88:9020/";

  /// 单例对象
  static NetWorkManager? _instance;

  /// 内部构造方法，可避免外部暴露构造函数，进行实例化
  NetWorkManager._internal();

  /// 工厂构造方法，这里使用命名构造函数方式进行声明
  factory NetWorkManager.getInstance() => _getInstance();

  // 网络进度条.
  static SizedBox? processSizeBox;

  /// 获取单例内部方法
  static _getInstance() {
    // 只能有一个实例
    if (_instance == null) {
      _instance = NetWorkManager._internal();
      processSizeBox = SizedBox(
        height: 100,
        width: 100,
        child: CircularProgressIndicator(
          backgroundColor: Colors.grey[200],
          valueColor: const AlwaysStoppedAnimation(Colors.blue),
        ),
      );
    }
    return _instance;
  }

  void clearCache(DataCallBack dataCallBack) async {
    GetStorage().erase();
    dataCallBack.businessCallBack??(true);
  }

  // 业务请求接口.
  void requestBussiness(
      String url,
      Map<String, dynamic> data,
      String method,
      DataCallBack dataCallback, {bool showLoading = false}) async {

     //做权限检查.
     bool isNetWork = await CommonUtil.checkNetWorkIsAvailable();
     if (!isNetWork) {
       Tips.showToast('网络不可用.');
       return;
     }

    var dio = Dio(BaseOptions(
      baseUrl: mServerHost,
      contentType:"application/json",
      sendTimeout: Duration(seconds: 20),
      receiveTimeout: Duration(seconds: 20)
    ));

    dio.interceptors.add(InterceptorsWrapper(
           onRequest: (requestOptions, handler) {
              logger.info('REQUEST[${requestOptions.method}] => PATH: ${requestOptions.path}, params: ${requestOptions.data}');
              String? loginToken = CommonUtil.getCurrentLoginToken();
              print('------loginToken---------> ${loginToken}');
              if (loginToken != '') {
                 // requestOptions.headers[AppConst.AUTHORIZATION] = 'Bearer' + ' ' + loginToken;
                requestOptions.headers[AppConst.XACCESS_Token] = loginToken;
              }
              return handler.next(requestOptions); //continue
           },
           onResponse: (response, handler) {
                Map<String, dynamic> data = response.data;
                logger.info('response data: ${json.encode(data)}');

                if (showLoading) {
                  Tips.dismissLoading();
                }
                if (data['code'] == 200) {
                  if (data['result'] != null) {
                    dataCallback.businessCallBack!(data['result']);
                  } else {
                    Tips.showToast(''+data['message']);
                    dataCallback.businessCallBack!('');
                  }

                } else {
                  if(dataCallback.errorCallBack != null) {
                    dataCallback.errorCallBack!(data['message']);
                  } else {
                    Tips.showToast(''+data['message']);
                  }

                }


           },
           onError: (DioException exception, handler) {
                if (showLoading) {
                   Tips.dismissLoading();
                }

                /*if (exception.response != null &&  exception.response!.statusCode == 401) {
                   //权限失效或未登录,则跳转登录页面.

                  Get.offAndToNamed(Routes.LOGIN);
                  //eventBus.fire(ProductContentEvent(ACCOUNT_TOKEN_UNVAILABLE));

                } else {*/
                  if(dataCallback.errorCallBack == null) {
                    Tips.showToast('服务器暂时失联.');
                    // Get.offAllNamed(Routes.LOGIN);
                  } else {
                    print('exception $exception');
                    print('check error $exception.message');
                    if(exception.response ==null){
                      var checkIsTimeout = exception.message.toString().contains("connectTimeout");
                      dataCallback.errorCallBack!(checkIsTimeout?'网络超时，请稍后重试':exception.message.toString());
                    }else{
                      dataCallback.errorCallBack!(exception.response.toString());
                    }

                  }
                //}


                return handler.next(exception); //continue
           }
    ));

    //dio设置.
    dio.interceptors.add(LogInterceptor(requestBody: true, responseBody: true));

    // print("请求参数: $data");

    if (showLoading) {
       Tips.showLoading();
    }

    dio.request<Map<String, dynamic>>(url,
            data: data,
            queryParameters: method == NetWorkManager.methodGET ? data : {},
            options: Options(method: method));

  }


  void uploadFileByFormData(String url, var file) {
    var dio = minedio.Dio(minedio.BaseOptions(
        baseUrl: NetWorkManager.mServerHost,
        contentType:"application/json"
    ));


    dio.interceptors.add(minedio.InterceptorsWrapper(
        onRequest: (requestOptions, handler) {

          /*User? currentUser = CommonUtil.getCurrentLoginUser();
          if (currentUser != null) {
            requestOptions.headers[AppConst.AUTHORIZATION] = currentUser!.tokenType! + ' ' + currentUser!.accessToken!;
          }*/

          requestOptions.headers['content-type'] = 'multipart/form-data';

          return handler.next(requestOptions); //continue
        },
        onResponse: (response, handler) {
          print('---response newest --->${response}');
          Map<String, dynamic> data = response.data;
          print('response data: ${json.encode(data)}');


        },
        onError: (minedio.DioException exception, handler) {
          print('---exception--->${exception.response?.statusCode!.toString()}');
          if (exception.response?.statusCode == 401) {
            Tips.showToast('token expired.');
          }
          return handler.next(exception); //continue
        }
    ));

    dio.post(
        url,
        data: file,
        onSendProgress: (sent,total) {
          final progress = (sent / total) * 100;
          print('上传进度: $progress%');
        }
    );
  }


  // downloadFile.
  void downloadFile (
      String url, String savePath, ProgressCallback progressCallback, CancelToken cancelToken)  {

    var dio = Dio(BaseOptions(
        baseUrl: mServerHost,

        contentType:"application/json"
    ));

    logger.info("下载URL为:" + url);

    try {
      dio.download(url, savePath,onReceiveProgress:  progressCallback,
          cancelToken: cancelToken,
          options: Options(
            followRedirects: false,
            validateStatus: (status) {
              return status! < 500;
            },
          )
      ).then((value)  {

        logger.info("文件URL为:${url}下载成功.");
      });
    } catch (e) {

      logger.info('Error during file download: $e');
    }

  }



  static String methodPOST = "POST";
  static String methodGET = "GET";
  static String methodDELETE = "DELETE";
  /// *****业务接口 Begin *********/
  ///
  static String SEND_PHONE_VERIFICATION_CODE = "sys/app_sms";
  static String SEND_EMAIL_VERIFICATION_CODE = "sys/app_email_code";

  static String SEND_PHONE_REGISTER = "sys/user/phone-register";
  static String SEND_EMAIL_REGISTER = "sys/user/email-Register";

  static String PHONE_Login = "sys/phoneLogin";
  static String M_Login = "sys/mLogin";

  static String SYS_LOGOUT = "sys/logout";
  static String AUDIO_AUTO_PLAY = 'speech/v1/tts/basic';

  static String FORGET_PHONE_PWD = "sys/user/phone-pwd";
  static String FORGET_EMAIL_PWD = "sys/user/email-pwd";

  static String SPEECH_RECOGNITION = 'speech/v1/recognition';
  static String TTS_REALTIME = 'speech/v1/tts/realtime';
  static String TEXT_2_TRANSLATE = 'mt/v1/text';
  static String Get_USER_INFOS = "sys/user/login/setting/getUserData";

  static String Edit_INFOS = "sys/user/login/setting/userEdit";
  static String TRANSLATE_PHOTOS="mt/v1/images";
  /******* 业务接口 End *********/

}

enum PostParamPosition {
  //请求参数放在消息头的参数中
  query,
  // 请求参数放在消息体中
  body
}
